/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.metadata.rtcustomization.servermanager.repository;

import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataPackage;
import com.inspur.edp.metadata.rtcustomization.api.entity.GspMdRefs;
import com.inspur.edp.metadata.rtcustomization.api.entity.InitilizedStatusEnum;
import com.inspur.edp.metadata.rtcustomization.servermanager.dac.CustomizationMetadataRefsRepository;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MetadataRefsRepoService {
    private CustomizationMetadataRefsRepository metadataRefsRepository;
    private final String INITIALIZE_STATUS = "INITIALIZE_STATUS";

    public MetadataRefsRepoService(CustomizationMetadataRefsRepository metadataRefsRepository) {
        this.metadataRefsRepository = metadataRefsRepository;
    }

    public List<GspMdRefs> getMdRefsByRefMdId(String metadataId) {
        return metadataRefsRepository.findAllByRefMdId(metadataId);
    }

    public void deleteByMdId(String metadataId) {
        metadataRefsRepository.deleteByMdId(metadataId);
    }

    public List<GspMdRefs> buildGspMdRefsByMetadataPackage(MetadataPackage mdPackage) {
        List<GspMdRefs> gspMdRefs = new ArrayList<>();
        if (mdPackage == null || CollectionUtils.isEmpty(mdPackage.getMetadataList())) {
            return gspMdRefs;
        }

        mdPackage.getMetadataList().forEach(metadata -> {
            List<GspMdRefs> gspMdRefsByMetadata = buildGspMdRefsByMetadata(metadata);
            gspMdRefs.addAll(gspMdRefsByMetadata);
        });

        return gspMdRefs;
    }

    public List<GspMdRefs> buildGspMdRefsByMetadata(GspMetadata metadata) {
        List<GspMdRefs> gspMdRefs = new ArrayList<>();
        if (CollectionUtils.isEmpty(metadata.getRefs())) {
            return gspMdRefs;
        }

        GspMdRefs mdRefs = new GspMdRefs(metadata.getHeader().getId(), metadata.getHeader().getCertId(), metadata.getHeader().getNameSpace(), metadata.getHeader().getCode(), metadata.getHeader().getType());

        metadata.getRefs().forEach(ref -> {
            // 存在重复数据不可添加
            if (gspMdRefs.stream().anyMatch(r -> r.getRefMdId().equals(ref.getDependentMetadata().getId()))) {
                return;
            }

            GspMdRefs clone = mdRefs.clone();
            // 由于是一对多，无法进行一对一更新，必须先删后增，删除的逻辑在外部控制。但是为了防止出现重复的mdId和refMdId，需要从表中获取id。
            // 4e40dbf3-cc70-4a28-aef8-ac8efb7e0481和17a48723-5a19-4242-9e59-1e42e122b159存在相同id不同code的情况，并且同时存在于"Inspur.GS.TM.CM.PaymentSettlementSupply.Front"包中
            List<GspMdRefs> oldMdRefs = metadataRefsRepository.findAllByMdIdAndRefMdId(metadata.getHeader().getId(), ref.getDependentMetadata().getId());
            String id = CollectionUtils.isEmpty(oldMdRefs) ? UUID.randomUUID().toString() : oldMdRefs.get(0).getId();
            clone.setId(id);
            clone.buildGspmdRefs(ref.getDependentMetadata().getId(), ref.getDependentMetadata().getCertId(), ref.getDependentMetadata().getNameSpace(), ref.getDependentMetadata().getCode(), ref.getDependentMetadata().getType());
            gspMdRefs.add(clone);
        });
        return gspMdRefs;
    }

    public void saveAll(List<GspMdRefs> gspMdRefs) {
        if (CollectionUtils.isEmpty(gspMdRefs)) {
            return;
        }
        metadataRefsRepository.saveAll(gspMdRefs);
    }


    public boolean isInitilized() {
        GspMdRefs mdRefs = metadataRefsRepository.findById("INITIALIZE_STATUS").orElse(null);
        return mdRefs != null && !InitilizedStatusEnum.NI.toString().equals(mdRefs.getMdCode());
    }

    public void setInitilizedStatus(InitilizedStatusEnum status) {
        GspMdRefs mdRefs = metadataRefsRepository.findById("INITIALIZE_STATUS").orElse(null);
        if (mdRefs == null) {
            mdRefs = new GspMdRefs(INITIALIZE_STATUS, UUID.randomUUID().toString(), status.toString(), UUID.randomUUID().toString());
        }
        mdRefs.setMdCode(status.toString());
        metadataRefsRepository.save(mdRefs);
    }
}
